package com.example.service.impl;

import com.example.constant.sta;
import com.example.info.SampleInfo;
import com.example.mapper.SampleMapper;
import com.example.pojo.FilterOptionsSample;
import com.example.pojo.PageResult;
import com.example.pojo.Sample;
import com.example.service.SampleService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SampleServiceImpl implements SampleService {

    @Autowired
    private SampleMapper sampleMapper;

    //分页查询数字样
    public PageResult page(Integer page, Integer pageSize){
        //设置分页参数
        PageHelper.startPage(page, pageSize);
        //执行查询
        List<Sample> list = sampleMapper.find();
        Page<Sample> p = (Page<Sample>) list;
        //封装分页结果
        return new PageResult(p.getTotal(), p.getResult());
    }

    //分页查询备选数字样
    public PageResult pageb(Integer page, Integer pageSize){
        //设置分页参数
        PageHelper.startPage(page, pageSize);
        //执行查询
        List<Sample> list = sampleMapper.findb();
        Page<Sample> p = (Page<Sample>) list;
        //封装分页结果
        return new PageResult(p.getTotal(), p.getResult());
    }

    //分页查询设备源数字样
    public PageResult pagem(Integer page, Integer pageSize){
        //设置分页参数
        PageHelper.startPage(page, pageSize);
        //执行查询
        List<Sample> list = sampleMapper.findm();
        Page<Sample> p = (Page<Sample>) list;
        //封装分页结果
        return new PageResult(p.getTotal(), p.getResult());
    }

    //分页查询正常图片
    public PageResult pagen(Integer page, Integer pageSize){
        //设置分页参数
        PageHelper.startPage(page, pageSize);
        //执行查询
        List<Sample> list = sampleMapper.findn();
        Page<Sample> p = (Page<Sample>) list;
        //封装分页结果
        return new PageResult(p.getTotal(), p.getResult());
    }

    //删除
    public void deleteById(Integer sampleID) {
        sampleMapper.deleteById(sampleID);
    }

    //修改备选数字样
    public void update(Sample sample){
        sample.setUpdateTime(LocalDateTime.now());
        sample.setDefectID(sampleMapper.getDefectIDByName(sample.getDefectName()));

        sampleMapper.update(sample);
    }

    //导入到下发数字样库
    public void upload(Sample sample){
        sample.setUpdateTime(LocalDateTime.now());
        sampleMapper.upload(sample);
    }



    //分页查询数字样并根据条件筛选
//    public PageResult pageWithFilter(Integer page, Integer pageSize, String brandName, String defectName, String defectGrade) {
//        //设置分页参数
//        PageHelper.startPage(page, pageSize);
//        //执行查询
//        //String defectType=sampleMapper.findDefectType(brandName,0);
//        //List<Sample> list=sampleMapper.findDigitalSampleMsg(defectType,brandName, defectGrade,0);
//        List<Sample> list = sampleMapper.findWithFilter(brandName, defectName, defectGrade, 0);
//        Page<Sample> p = (Page<Sample>) list;
//        //封装分页结果
//        return new PageResult(p.getTotal(), p.getResult());
//    }
    //分页查询数字样并根据条件筛选
    public PageResult pageWithFilter(Integer page, Integer pageSize,
                                     List<String> brandNames,
                                     List<String> defectNames,
                                     List<String> defectGrades) {
        // 1. 获取全量数据（使用原有Mapper方法）
        List<Sample> allSamples = sampleMapper.find();

        // 2. 内存过滤（保持链式过滤顺序优化性能）
        List<Sample> filtered = allSamples.stream()
                .filter(sample -> filterByBrand(sample, brandNames))
                .filter(sample -> filterByDefect(sample, defectNames))
                .filter(sample -> filterByGrade(sample, defectGrades))
                .collect(Collectors.toList());

        //清空sta.fileList
        sta.fileList.clear();
        //遍历filtered，将filename添加到sta.fileList，如果有重复的则不添加
        for (Sample sample : filtered) {
            if (!sta.fileList.contains(sample.getFileName())) {
                sta.fileList.add(sample.getFileName());
            }
        }

        // 3. 手动分页计算
        int total = filtered.size();
        int totalPages = (int) Math.ceil((double) total / pageSize);

        // 处理页码越界
        page = Math.max(1, Math.min(page, totalPages));

        // 计算分页区间
        int fromIndex = (page - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);

        // 4. 封装结果
        return new PageResult(
                (long) total,
                filtered.subList(fromIndex, toIndex)
        );
    }
    //分页查询备选数字样并根据条件筛选
    public PageResult pagebWithFilter(Integer page, Integer pageSize,
                                     List<String> brandNames,
                                     List<String> defectNames,
                                     List<String> defectGrades, List<Double> NPS) {
        // 1. 获取全量数据（使用原有Mapper方法）
        List<Sample> allSamples = sampleMapper.findb();

        // 2. 内存过滤（保持链式过滤顺序优化性能）
        List<Sample> filtered = allSamples.stream()
                .filter(sample -> filterByBrand(sample, brandNames))
                .filter(sample -> filterByDefect(sample, defectNames))
                .filter(sample -> filterByGrade(sample, defectGrades))
                .filter(sample -> filterByNPS(sample, NPS))
                .collect(Collectors.toList());

        // 3. 手动分页计算
        int total = filtered.size();
        int totalPages = (int) Math.ceil((double) total / pageSize);

        // 处理页码越界
        page = Math.max(1, Math.min(page, totalPages));

        // 计算分页区间
        int fromIndex = (page - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);

        // 4. 封装结果
        return new PageResult(
                (long) total,
                filtered.subList(fromIndex, toIndex)
        );
    }

    // 品牌过滤逻辑
    private boolean filterByBrand(Sample sample, List<String> brands) {
        if (CollectionUtils.isEmpty(brands)) return true;
        return brands.contains(sample.getBrandName());
    }
    // 缺陷名称过滤
    private boolean filterByDefect(Sample sample, List<String> defects) {
        if (CollectionUtils.isEmpty(defects)) return true;
        return defects.contains(sample.getDefectName());
    }
    // 缺陷等级过滤
    private boolean filterByGrade(Sample sample, List<String> grades) {
        if (CollectionUtils.isEmpty(grades)) return true;
        return grades.contains(sample.getDefectGrade());
    }
    // 推荐指数过滤
    private boolean filterByNPS(Sample sample, List<Double> NPS) {
        if (CollectionUtils.isEmpty(NPS)) return true;
        return NPS.contains(sample.getNPS());
    }
    //设备编号（machineID）过滤
    private boolean filterByMachineID(Sample sample, List<String> machineIDs) {
        if (CollectionUtils.isEmpty(machineIDs)) return true;
        return machineIDs.contains(sample.getMachineID());
    }



    //向digitalsample表中插入数据
    public void save(Sample sample) {
        sample.setCreateTime(LocalDateTime.now());
        sample.setUpdateTime(LocalDateTime.now());
        sampleMapper.save(sample);
    }

    //向digitalsamplemachine表中插入数据
    public void savem(Sample sample) {
        sample.setCreateTime(LocalDateTime.now());
        sample.setUpdateTime(LocalDateTime.now());
        sampleMapper.savem(sample);
    }


    //从数字样库中获取所有不同的品牌名称、缺陷名称和缺陷等级
    public FilterOptionsSample getDistinctFilterOptions() {
        FilterOptionsSample options = new FilterOptionsSample();
        options.setBrandNames(sampleMapper.getDistinctBrandNames());
        options.setDefectNames(sampleMapper.getDistinctDefectNames());
        options.setDefectGrades(sampleMapper.getDistinctDefectGrades());
        return options;
    }
    //从备选数字样库中获取所有不同的品牌名称、缺陷名称、缺陷等级和推荐指数
    public FilterOptionsSample getDistinctFilterOptionsb() {
        FilterOptionsSample options = new FilterOptionsSample();
        options.setBrandNames(sampleMapper.getDistinctBrandNamesb());
        options.setDefectNames(sampleMapper.getDistinctDefectNamesb());
        options.setDefectGrades(sampleMapper.getDistinctDefectGradesb());
        options.setNPS(sampleMapper.getDistinctNPS());
        return options;
    }

    //获取设备源图库所有不同设备编号，品牌和缺陷类型
    public FilterOptionsSample getDistinctFilterOptionsm() {
        FilterOptionsSample options = new FilterOptionsSample();
        options.setMachineIDs(sampleMapper.getDistinctMachineIDs());
        options.setBrandNames(sampleMapper.getDistinctBrandNamesm());
        options.setDefectNames(sampleMapper.getDistinctDefectTypesm());
        return options;
    }

    // 获取正常图片所有品牌名称
    public FilterOptionsSample getDistinctFilterOptionsn() {
        FilterOptionsSample options = new FilterOptionsSample();
        options.setMachineIDs(sampleMapper.getDistinctMachineIDsn());
        options.setBrandNames(sampleMapper.getDistinctBrandNamesn());
        return options;
    }


    // 新增缺陷名称到类型的映射方法
    private List<String> getDefectTypes(List<String> defectNames) {
        if (CollectionUtils.isEmpty(defectNames)) return Collections.emptyList();
        return defectNames.stream()
                .flatMap(name -> sampleMapper.findDefectTypesByName(name).stream())
                .distinct()
                .collect(Collectors.toList());
    }

    public PageResult pagemWithFilter(Integer page, Integer pageSize, List<String> machineIDs, List<String> brands,
                                      List<String> defects, Date start, Date end) {
        // 获取全量数据
        List<Sample> allSamples = sampleMapper.findm();

        // 获取缺陷类型映射
        List<String> defectTypes = getDefectTypes(defects);

        // 内存过滤
        List<Sample> filtered = allSamples.stream()
                .filter(s -> filterByMachineID(s, machineIDs))
                .filter(s -> filterByBrand(s, brands))
                .filter(s -> filterByDefectType(s, defectTypes))
                .filter(s -> filterByTime(s.getPostTime(), start, end))
                .collect(Collectors.toList());

        // 手动分页（与原有代码逻辑一致）
        return manualPagination(filtered, page, pageSize);
    }

    public PageResult pagenWithFilter(Integer page, Integer pageSize, List<String> machineIDs, List<String> brands,
                                      Date start, Date end) {
        // 获取全量数据
        List<Sample> allSamples = sampleMapper.findn();

        // 内存过滤
        List<Sample> filtered = allSamples.stream()
                .filter(s -> filterByBrand(s, brands))
                .filter(s -> filterByMachineID(s, machineIDs))
                .filter(s -> filterByTime(s.getPostTime(), start, end))
                .collect(Collectors.toList());

        // 手动分页
        return manualPagination(filtered, page, pageSize);
    }

    private boolean filterByDefectType(Sample sample, List<String> defectTypes) {
        return CollectionUtils.isEmpty(defectTypes) ||
                defectTypes.contains(sample.getDefectType());
    }

//    private boolean filterByTime(Date time, Date start, Date end) {
//        if (start == null && end == null) return true;
//        long timestamp = time.getTime();
//        return (start == null || timestamp >= start.getTime()) &&
//                (end == null || timestamp <= end.getTime());
//    }
    private boolean filterByTime(Date time, Date start, Date end) {
        // 处理time为null的情况
        if (time == null) {
            // 当时间为空时，仅在未设置时间筛选条件时保留该记录
            return (start == null && end == null);
        }
        long timestamp = time.getTime();
        return (start == null || timestamp >= start.getTime()) &&
                (end == null || timestamp <= end.getTime());
    }

    // 共用分页方法（与原有pageWithFilter逻辑一致）
    private PageResult manualPagination(List<Sample> data, int page, int pageSize) {
        int total = data.size();
        int totalPages = (int) Math.ceil((double) total / pageSize);
        page = Math.max(1, Math.min(page, totalPages));

        int fromIndex = (page - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);

        return new PageResult((long)total, data.subList(fromIndex, toIndex));
    }
}
